import { 
    Injectable, 
    NotFoundException, 
    BadRequestException,
    Logger 
  } from '@nestjs/common';
  import { 
    Repository, 
    FindManyOptions, 
    FindOptionsWhere, 
    DeepPartial 
  } from 'typeorm';
  import { BaseEntity } from '../entity/base.entity';
  import { PaginationDto } from '../dto/base.dto';
  import { PaginationResult, ApiResponse } from '../interfaces/base.interface';
  
  @Injectable()
  export abstract class BaseCrudService<T extends BaseEntity> {
    protected readonly logger = new Logger(this.constructor.name);
  
    constructor(protected readonly repository: Repository<T>) {}
  
    // 创建记录
    async create(createData: DeepPartial<T>): Promise<ApiResponse<T>> {
      try {
        // 确保设置时间戳
        const now = new Date();
        const entityData = {
          ...createData,
          createdAt: createData.createdAt || now,
          updatedAt: createData.updatedAt || now,
        };
        
        const entity = this.repository.create(entityData);
        const savedEntity = await this.repository.save(entity);
        
        this.logger.log(`Created ${this.constructor.name} with ID: ${savedEntity.id}`);
        
        return {
          success: true,
          data: savedEntity,
          message: '创建成功'
        };
      } catch (error) {
        this.logger.error(`Failed to create ${this.constructor.name}:`, error);
        return {
          success: false,
          error: error.message || '创建失败'
        };
      }
    }
  
    // 查询所有记录（分页）
    async findAll(
      paginationDto: PaginationDto,
      whereConditions?: FindOptionsWhere<T>,
      relations?: string[]
    ): Promise<ApiResponse<PaginationResult<T>>> {
      try {
        const { page, pageSize, sortBy, sortOrder } = paginationDto;
        const skip = (page - 1) * pageSize;
  
        const options: FindManyOptions<T> = {
          where: whereConditions,
          skip,
          take: pageSize,
          relations,
        };
  
        // 动态排序
        if (sortBy) {
          options.order = { [sortBy]: sortOrder } as any;
        } else {
          options.order = { createdAt: sortOrder } as any;
        }
  
        const [data, total] = await this.repository.findAndCount(options);
  
        const result: PaginationResult<T> = {
          data,
          total,
          page,
          pageSize,
          totalPages: Math.ceil(total / pageSize),
        };
  
        return {
          success: true,
          data: result,
          message: '查询成功'
        };
      } catch (error) {
        this.logger.error(`Failed to find all ${this.constructor.name}:`, error);
        return {
          success: false,
          error: error.message || '查询失败'
        };
      }
    }
  
    // 根据ID查询单条记录
    async findOne(
      id: string, 
      relations?: string[]
    ): Promise<ApiResponse<T>> {
      try {
        const entity = await this.repository.findOne({
          where: { id } as any,
          relations,
        });
  
        if (!entity) {
          return {
            success: false,
            error: `ID为 ${id} 的记录不存在`
          };
        }
  
        return {
          success: true,
          data: entity,
          message: '查询成功'
        };
      } catch (error) {
        this.logger.error(`Failed to find ${this.constructor.name} by ID:`, error);
        return {
          success: false,
          error: error.message || '查询失败'
        };
      }
    }
  
    // 更新记录
    async update(
      id: string, 
      updateData: DeepPartial<T>
    ): Promise<ApiResponse<T>> {
      try {
        const existingEntity = await this.repository.findOne({
          where: { id } as any
        });
  
        if (!existingEntity) {
          return {
            success: false,
            error: `ID为 ${id} 的记录不存在`
          };
        }
  
        // 合并更新数据
        Object.assign(existingEntity, updateData);
        const updatedEntity = await this.repository.save(existingEntity);
  
        this.logger.log(`Updated ${this.constructor.name} with ID: ${id}`);
  
        return {
          success: true,
          data: updatedEntity,
          message: '更新成功'
        };
      } catch (error) {
        this.logger.error(`Failed to update ${this.constructor.name}:`, error);
        return {
          success: false,
          error: error.message || '更新失败'
        };
      }
    }
  
    // 删除记录
    async remove(id: string): Promise<ApiResponse<void>> {
      try {
        const entity = await this.repository.findOne({
          where: { id } as any
        });
  
        if (!entity) {
          return {
            success: false,
            error: `ID为 ${id} 的记录不存在`
          };
        }
  
        await this.repository.remove(entity);
        
        this.logger.log(`Deleted ${this.constructor.name} with ID: ${id}`);
  
        return {
          success: true,
          message: '删除成功'
        };
      } catch (error) {
        this.logger.error(`Failed to delete ${this.constructor.name}:`, error);
        return {
          success: false,
          error: error.message || '删除失败'
        };
      }
    }
  
    // 批量删除
    async batchRemove(ids: string[]): Promise<ApiResponse<void>> {
      try {
        await this.repository.delete(ids);
        
        this.logger.log(`Batch deleted ${this.constructor.name} with IDs: ${ids.join(', ')}`);
  
        return {
          success: true,
          message: `成功删除 ${ids.length} 条记录`
        };
      } catch (error) {
        this.logger.error(`Failed to batch delete ${this.constructor.name}:`, error);
        return {
          success: false,
          error: error.message || '批量删除失败'
        };
      }
    }
  
    // 统计记录数量
    async count(whereConditions?: FindOptionsWhere<T>): Promise<ApiResponse<number>> {
      try {
        const total = await this.repository.count({ where: whereConditions });
        
        return {
          success: true,
          data: total,
          message: '统计成功'
        };
      } catch (error) {
        this.logger.error(`Failed to count ${this.constructor.name}:`, error);
        return {
          success: false,
          error: error.message || '统计失败'
        };
      }
    }
  
    // 检查记录是否存在
    async exists(id: string): Promise<boolean> {
      try {
        const count = await this.repository.count({
          where: { id } as any
        });
        return count > 0;
      } catch (error) {
        this.logger.error(`Failed to check existence of ${this.constructor.name}:`, error);
        return false;
      }
    }
  }